package com.booklove.controller.order;


import com.booklove.constant.DonateStateConstant;
import com.booklove.constant.JudgeStateConstant;
import com.booklove.constant.OrderTypeConstant;
import com.booklove.constant.WishStateConstant;
import com.booklove.context.BaseContext;

import com.booklove.domain.dto.OrdersFormDonateDTO;
import com.booklove.domain.dto.OrdersFormTakeDTO;
import com.booklove.domain.dto.PageDTO;
import com.booklove.domain.po.*;

import com.booklove.domain.query.OrdersQuery;
import com.booklove.domain.vo.OrdersVO;
import com.booklove.exception.AddressSubmitException;
import com.booklove.exception.OrderBusinessException;
import com.booklove.result.Result;

import com.booklove.service.book.BooksService;
import com.booklove.service.book.DonatebookService;
import com.booklove.service.book.WishbookService;
import com.booklove.service.delivery.AddressService;
import com.booklove.service.delivery.DeliverService;
import com.booklove.service.order.OrdersService;
import com.booklove.service.voluntary.VoluntaryworkService;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;


@Slf4j
@RestController("ordersCLL")
@RequestMapping("/orders")
@RequiredArgsConstructor// 使用基本注解的注入形式，仅仅注入需要的变量
public class OrdersController {

    private final OrdersService ordersService;

    private final DeliverService deliverService;

    private final VoluntaryworkService voluntaryworkService;

    private final DonatebookService donatebookService;

    private final WishbookService wishbookService;

    private final AddressService addressService;

    private final BooksService booksService;

    @Data
    @Builder
    static class CreateOrderMsg {
        Integer deliverId;
        Integer userShopId;
        Integer addressStartId;
        Integer addressEndId;

    }

    /**
     * 创建一个自动生成的订单，然后返回派送deliverID
     * @param addressStartId
     * @param addressEndId
     * @param orderType
     * @param orderDonateOrWishId
     * @return
     */
    CreateOrderMsg createDeliverAndVoluntaryWork(Integer addressStartId, Integer addressEndId, Integer orderType, Integer orderDonateOrWishId) {
        // 第二个id为空，被点击者的id
        Integer userShopId = null;

        // 获取捐书信息，然后填写一些信息
        Voluntarywork voluntarywork = new Voluntarywork();
        if (orderType == OrderTypeConstant.IS_DONATE) { // 如果是想提供这本书，检测这个愿望是否存在
            Wishbook wishbook = wishbookService.getById(orderDonateOrWishId);

            if (wishbook == null || wishbook.getJudgeState() != JudgeStateConstant.ACCEPT) {
                throw new OrderBusinessException("非法的订单创建，此次提交未存在合法的许愿书籍信息");
            }
            if (wishbook.getWishState() == WishStateConstant.DONE) {
                throw new OrderBusinessException("愿望已经结束了");
            }

            userShopId = wishbook.getUserId();

            Books books = booksService.getById(wishbook.getBookId());
            // 创建志愿任务
            voluntarywork = Voluntarywork.createVoluntaryWork(
                    "书本派送任务:" + books.getName(),
                    books.getName()
                    , books.getCover()
            );

            wishbook.setWishState(WishStateConstant.DONE);
            wishbookService.updateById(wishbook);
            // 获取终点id
            addressEndId = wishbook.getAddressId();

        } else if (orderType == OrderTypeConstant.IS_TAKE) { // 如果是想要这本书，检查这本书是否送了
            Donatebook donatebook = donatebookService.getById(orderDonateOrWishId);

            if (donatebook == null || donatebook.getJudgeState() != JudgeStateConstant.ACCEPT) {
                throw new OrderBusinessException("非法的订单创建，此次提交未存在捐赠书籍信息，或是发生其他异常");
            }
            if (donatebook.getDonateState() == DonateStateConstant.DONE) // 如果是领取结束的书本，不允许领取
            {
                throw new OrderBusinessException("书籍已经没有了");
            }

            // 被动生成订单的userid
            userShopId = donatebook.getUserId();

            Books books = booksService.getById(donatebook.getBookId());
            // 创建志愿任务
            voluntarywork = Voluntarywork.createVoluntaryWork(
                    "书本派送任务:" + books.getName(),
                    books.getName()
                    , books.getCover()
            );

            // 设置为已经结束
            donatebook.setDonateState(
                    DonateStateConstant.DONE
            );
            donatebookService.updateById(donatebook);

            // 获取终点id
            addressStartId = donatebook.getAddressId();

        }

        if (addressStartId == null || addressEndId == null) {
            throw new OrderBusinessException("派送终点或者起点存在异常");
        }

        // 创建一个派送任务
        Deliver deliver = new Deliver();
        deliver.setAddressEndId(addressStartId); // 设置起点
        deliver.setAddressEndId(addressEndId); // 设置终点
        deliverService.save(deliver);


        // 回填派送ID
        voluntarywork.setDeliverId(deliver.getId());
        voluntaryworkService.save(voluntarywork);

        return CreateOrderMsg.builder()
                .deliverId(deliver.getId())
                .userShopId(userShopId)
                .build();
    }

    /**
     * 保存新增
     * 回应wish愿望的时候主动捐献
     * 点击我要回应这个愿望的时候，填入回应者的userId
     *
     */
    @Transactional
    @PostMapping("/Donate")
//    TODO 测试回应许愿 完善许愿的judge
    public Result<String> createDonateOrders(@RequestBody OrdersFormDonateDTO ordersFormDonateDTO) {
        Integer addressId = ordersFormDonateDTO.getAddressStartId();
        Address address = addressService.getById(addressId);
        if (address == null || address.getUserId() != BaseContext.getCurrentId().intValue()) {
            throw new AddressSubmitException("提供的地址信息非法，请检测你的地址");
        }


        CreateOrderMsg createOrderMsg = createDeliverAndVoluntaryWork(
                ordersFormDonateDTO.getAddressStartId(),
                null, // 终点在函数中回填进去
                OrderTypeConstant.IS_DONATE,
                ordersFormDonateDTO.getWishBookId()
        );


        // 创建
        Orders orders = Orders.createDonateOrder(ordersFormDonateDTO);
        // 回填派送id
        orders.setDeliverId(createOrderMsg.getDeliverId());
        // 回填用户id -- 此处记录的是提交者的id，即为回应愿望的id
        orders.setUserId(BaseContext.getCurrentId().intValue());
        // 回填user_shop_id
        orders.setUserShopId(createOrderMsg.getUserShopId());


        ordersService.save(orders);
        return Result.success();
    }

    /**
     * 保存新增
     * 在捐书平台点击我想要
     * 点击我要这个书本的时候会将自己的userId填入，然后创建订单
     */
    @Transactional
    @PostMapping("/take")
    public Result<String> createTakeOrders(@RequestBody OrdersFormTakeDTO ordersFormTakeDTO) {
        Integer addressId = ordersFormTakeDTO.getAddressStartId();
        Address address = addressService.getById(addressId);
        if (address == null || address.getUserId() != BaseContext.getCurrentId().intValue()) {
            throw new AddressSubmitException("提供的地址信息非法，请检测你的地址");
        }


        CreateOrderMsg createOrderMsg = createDeliverAndVoluntaryWork(
                null,//起点在函数中查询回填进去
                ordersFormTakeDTO.getAddressEndId(),
                OrderTypeConstant.IS_TAKE,
                ordersFormTakeDTO.getDonateBookId()
        );

        // 创建
        Orders orders = Orders.createTakeOrder(ordersFormTakeDTO);
        // 回填派送id
        orders.setDeliverId(createOrderMsg.getDeliverId());
        // 回填用户id 此处记录的是提交者的id，即为主动选择拿去这本书籍的人的的id
        orders.setUserId(BaseContext.getCurrentId().intValue());
        // 回填user_shop_id
        orders.setUserShopId(createOrderMsg.getUserShopId());

        ordersService.save(orders);
        return Result.success();
    }


    /**
     * 删除数据
     *
     * @param id 主键
     * @return 删除是否成功
     */
    @DeleteMapping("/id")
    Result<String> deleteOrders(@RequestParam("id") Long id) {
        ordersService.removeById(id);
        return Result.success();
    }


    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/{id}")
    Result<OrdersVO> getOrdersVO(@PathVariable Integer id) {
        return Result.success(ordersService.getByVOId(id));
    }


    /**
     * 分页查询
     *
     * @param ordersQuery 筛选条件
     * @return 查询结果
     */
    @GetMapping("/page")
    PageDTO<OrdersVO> orderssPageQuery(OrdersQuery ordersQuery) {
        return ordersService.queryOrderssPage(ordersQuery);
    }


}

